#!/usr/bin/python
import os
import sys
import fcntl
import posixpath

ATTR_ARCH = 0x20
ATTR_DIR = 0x10
ATTR_VOLUME = 0x08
ATTR_SYSTEM = 0x04
ATTR_HIDDEN = 0x02
ATTR_RO = 0x01

AttrBitName = {
    ATTR_ARCH: 'A',
    ATTR_DIR: 'D',
    ATTR_VOLUME: 'V',
    ATTR_SYSTEM: 'S',
    ATTR_HIDDEN: 'H',
    ATTR_RO: 'R',
}

AttrBits = AttrBitName.keys()
AttrBits.sort()
AttrBits.reverse()
 
FAT_GETATTR_IOCTL = 0x80047210
FAT_SETATTR_IOCTL = 0x40047211

def fat_getattr(filename):
  fd = os.open(filename, os.O_RDONLY)
  try:
    word = fcntl.ioctl(fd, FAT_GETATTR_IOCTL, '    ')
  except:
    os.close(fd)
    raise
  os.close(fd)
  return ord(word[0])

def fat_setattr(filename, attr):
  fd = os.open(filename, os.O_RDONLY)
  word = '%s\0\0\0' % chr(attr)
  try:
    fcntl.ioctl(fd, FAT_SETATTR_IOCTL, word)
  except:
    os.close(fd)
    raise
  os.close(fd)

def fat_attrstr(attr):
  bit_to_name = lambda bit: bit & attr and AttrBitName[bit] or '.'
  return ''.join(map(bit_to_name, AttrBits))

def fat_strattr(str):
  str_to_bin = lambda x: x[0] == x[1] and '1' or '0'
  bin = ''.join(map(str_to_bin, zip('ADVSHR', str)))
  return int(bin, 2)

def fat_extattr(attr):
  return attr & (ATTR_VOLUME | ATTR_SYSTEM | ATTR_HIDDEN) #ATTR_ARCH 

def fat_dumpattr():
  for cur, dirs, files in os.walk('.'):
    items = dirs + files
    for item in items:
      try:
        filename = '%s/%s' % (cur, item)
        attr = fat_getattr(filename)
        if not fat_extattr(attr):
          continue
        str = fat_attrstr(attr)
        print '%s     %s' % (str, filename)
      except Exception, e:
        print e

def fat_loadattr():
  for line in sys.stdin.readlines():
    str = line[:6]
    file = line[6:].strip()
    if posixpath.exists(file):
      newattr = fat_strattr(str)
      oldattr = fat_getattr(file)
      if newattr == oldattr:
        print 'ignore same attribute %s[0x%02x]: %s' % (str, newattr, file)
      else:
        oldstr = fat_attrstr(oldattr)
        fat_setattr(file, newattr)
        print '-%s[0x%02X] +%s[0x%02X] %s' % (oldstr, oldattr, str, newattr, file)
    else:
      print 'ignore not existing file: %s' % file

target_dir = sys.argv[1]
old_dir = os.getcwd()
os.chdir(target_dir)

op = sys.argv[2]
if op == 'dump':
  fat_dumpattr()
elif op == 'load':
  fat_loadattr()

os.chdir(old_dir)
